package com.warm.micro.consumer.config;

import com.netflix.loadbalancer.IPing;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RoundRobinRule;
import com.netflix.niws.loadbalancer.NIWSDiscoveryPing;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

/**
 * @Date: 2020/5/9 10:20
 * @Author: LChuang
 * @Description: RestTemplate 配置类
 */
@Configuration
public class RestConfig {

    /**
     * Ribbon 核心 ServerList
     * ServerList 是 Ribbon 存储的可用服务列表
     * ServerList 可以手动设置
     * ServerList 常见应用是从Eureka中自动获取
     */

    /**
     * Ribbon 天然与 Eureka 无缝整合
     * 通过 @LoadBalanced 提供负载均衡支持
     * 通过ribbon.eureka.enabled=false 禁用 Eureka
     *
     * 哪些内容能被负载均衡 : serverList
     */
    /**
     * RestTemplate: Spring 提供的一个访问Http服务的客户端类 --> 微服务之间的调用就是使用 RestTemplate
     * @LoadBalanced 注解表示使用Ribbon实现客户端负载均衡 --> 可以通过微服务的名字从 Eureka 中找到对应的服务并访问了
     */
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

    /**
     * 怎么负载均衡：
     * Ribbon 核心 IRule (负载均衡规则) : allServerList, upServerList
     * RoundRobinRule : 轮询规则
     * RandomRule : 随机规则
     * AvailabilityFilteringRule : 可用过滤规则
     * WeightedResponseTimeRule : 根据平均响应时间计算所有服务的权重 (常用)
     * RetryRule : 遵循RoundRobin规则处理,  但是会对失败的服务进行重试
     * BestAvailableRule : 结合了可用过滤规则和响应时长规则 (常用)
     * ZoneAvoidanceRule : 复合判断server所在区域性能和可用性选择服务器
     */
    @Bean
    public IRule iRule() {
        return new RoundRobinRule();
//        return new MyRule();
    }

    /**
     * IPing 保证Ribbon 保证服务可用的基石
     * 实现:
     * NIWSDiscoveryPing : 不执行Ping操作, 根据Eureka Client 的反馈判断存活
     * PingUrl : 使用HttpClient对服务进行Ping操作
     * DummyPing : 默认返回true
     * NoOpPing : 永远返回true
     */
    @Bean
    public IPing iPing() {
//        return new PingUrl(false,"/abc");
        return new NIWSDiscoveryPing();
    }

    /**
     * Ribbon 参数配置
     *  默认参数配置
     *  Ribbon Key定义
     *  Ribbon参数分为全局配置和指定客户端配置
     *  参数格式: <client>.ribbon.<key>=<value>
     *      全局配置：ribbon.key=value
     *      执行服务配置：server.ribbon.key=value
     */
}
